
package graphics3d;

import java.awt.Graphics;


public class Object3d extends Motion {
    
    protected final Ribs ribs;
    protected final int numberOfVertexes;
    
    protected Graphics g;
    
    protected Matrix currentObject = this.object;
    
    private Matrix projectObject;
    private double zCamera;
    
    public Object3d(Matrix object) {
        this(object, 0);
    }
    public Object3d(Matrix object, Ribs ribs) {
        this(object, ribs, 0);
    }
    public Object3d(Matrix object, int pivot_point) {
        super(object, pivot_point);
        numberOfVertexes = object.numberOfColumns();
        ribs = new Ribs(numberOfVertexes);
    }
    public Object3d(Matrix object, Ribs ribs, int pivot_point) {
        super(object, pivot_point);
        numberOfVertexes = object.numberOfColumns();
        this.ribs = ribs;
    }
    
    public void draw(Graphics g, int frameWidth, int frameHeight, int L, int R, int B, int T, double zCamera) {
        
        this.g = g;
        this.zCamera = zCamera;
        currentObject = conversions.multiply(object);
        projectObject = projectMatrix().multiply(currentObject);
        for (int i = 0; i < numberOfVertexes; i++)
            drawDot(getX(i), getY(i), L, R, B, T, frameWidth, frameHeight);
        for (int i = 0; i < numberOfVertexes; i++)
            for (int j = i+1; j < numberOfVertexes; j++)
                if(ribs.isConnected(i, j)) drawLine(getX(i), getY(i), getX(j), getY(j), L, R, B, T, frameWidth, frameHeight);
    }
    
    private Matrix projectMatrix() {
        double arr[] = new double[] {1, 0,          0, 0,
                                     0, 1,          0, 0,
                                     0, 0,          0, 0,
                                     0, 0, -1/zCamera, 1};
        return new Matrix(4, arr);
    }
        
    private double getX(int i) {
        double a = zCamera/(zCamera - currentObject.cell(2, i));
        return a*projectObject.cell(0, i);
    }
    private double getY(int i) {
        double a = zCamera/(zCamera - currentObject.cell(2, i));
        return a*projectObject.cell(1, i);
    }
    
    protected void drawDot(double x, double y, double L, double R, double B, double T, int frameWidth, int frameHeight) {
        int screenX = xFromDec(x, L, R, frameWidth);
        int screenY = yFromDec(y, B, T, frameHeight);
        g.drawLine(screenX, screenY, screenX, screenY);
    }
    protected void drawLine(double x1, double y1, double x2, double y2, double L, double R, double B, double T, int frameWidth, int frameHeight) {
        int screenX1 = xFromDec(x1, L, R, frameWidth);
        int screenY1 = yFromDec(y1, B, T, frameHeight);
        int screenX2 = xFromDec(x2, L, R, frameWidth);
        int screenY2 = yFromDec(y2, B, T, frameHeight);
        g.drawLine(screenX1, screenY1, screenX2, screenY2);
    }
    
    private int xFromDec(double x, double L, double R, int frameWidth) {
        return (int) ((x-L) / (R-L) * frameWidth);
    }
    private int yFromDec(double y, double B, double T, int frameHeight) {
        return (int) ((T-y) / (T-B) * frameHeight);
    }
    
}
